﻿using DreamSpace.Net.Extensions;
using DreamSpace.Net.ScriptEngines;
using DreamSpace.Net.ScriptEngines.V8;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common;

namespace DreamSpace.Net
{
    public partial class DreamSpaceServer
    {
        /// <summary>
        /// A list of server host instances. Each instance runs on a separate thread.
        /// A special global object property 'globals' can be used to share data between the threads, with optional thread blocking using the 'lock(globals)' statement.
        /// </summary>
        public IEnumerable<IServerHost<IScriptEngine>> ServerHosts { get { return _ServerHosts.Select(sh => sh); } } //TODO: Check if able to get access to '_ServerHosts' by casting.
        List<IServerHost<IScriptEngine>> _ServerHosts;

        public IEnumerable<IDSSExtension> Modules { get { return _Modules.Select(m => m); } } //TODO: Check if able to get access to '_Modules' by casting.
        List<IDSSExtension> _Modules;

        /// <summary>
        /// A list of globally shared values that can be access across many server hosts.
        /// Be sure to lock the object before accessing it.
        /// </summary>
        public readonly Dictionary<string, object> Globals = new Dictionary<string, object>();

        public DreamSpaceServer()
        {
            _ServerHosts = new List<IServerHost<IScriptEngine>>(8);
            _Modules = new List<IDSSExtension>(32);
        }

        void _AddCoreModules() // Looks for IDSSExtension objects included by default in the current assembly. 
        {
        }

        public void RegisterModule(IDSSExtension module)
        {
            if (!_Modules.Contains(module))
                _Modules.Add(module);
        }

        /// <summary>
        /// Merges the modules in the specified namespace into the global "DreamSpace.NET" environment space.
        /// This removes the need to specify a namespace when accessing a module (i.e. when calling 'Uses(...)').
        /// </summary>
        /// <param name="moduleNamespace">The namespace of an installed module to flatten (case sensitive).</param>
        public void FlattenModuleNamespace(string moduleNamespace)
        {
            if (!moduleNamespace.IsNullOrWhiteSpace() && moduleNamespace != "DreamSpace.NET")
            {
                //...
            }
        }

        public ServerHost<TScriptEngine> CreateServerHost<TScriptEngine>(TScriptEngine engine = null)
            where TScriptEngine : class, IScriptEngine
        {
            var sh = new ServerHost<TScriptEngine>(this, engine);
            _ServerHosts.Add((IServerHost<IScriptEngine>)sh);
            return sh;
        }

        public ServerHost<V8ScriptEngine> CreateV8ServerHost(V8ScriptEngine engine = null)
        {
            var sh = new ServerHost<V8ScriptEngine>(this, engine);
            _ServerHosts.Add((IServerHost<IScriptEngine>)sh);
            return sh;
        }
    }
}
